/**
 @file sys_usw_port.c

 @author  Copyright (C) 2011 Centec Networks Inc.  All rights reserved.

 @date 2020-11-14

 @version v2.0

*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_interrupt.h"
#include "ctc_warmboot.h"
#include "sys_usw_common.h"
#include "sys_tsingma_datapath.h"
#include "sys_tsingma_port.h"
#include "sys_tsingma_mac.h"
#include "sys_usw_chip.h"
#include "sys_usw_peri.h"
#include "sys_tsingma_peri.h"
#include "sys_usw_dmps.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_port_api.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_mcu.h"
#include "sys_tsingma_mcu.h"
#include "sys_usw_register.h"
#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "usw/include/drv_chip_ctrl.h"

/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/

/****************************************************************************
 *
* Function
*
*****************************************************************************/
STATIC int32
_sys_tsingma_port_get_chan_framesize(uint8 lchip, uint32 chan_id, uint32 gport, uint32* p_value, sys_port_framesize_type_t type)
{
    uint32 cmd = 0;
    uint32 dp_id = 0;
    uint32 index = 0;
    uint32 dp_chan_id = 0;
    uint32  pp_id = 0;
    ds_t   ds;
    
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        dp_id = (chan_id < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))? 0:1;
        dp_chan_id = (chan_id < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))? chan_id:(chan_id - MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM));
        index = DRV_INS(dp_id, dp_chan_id);
    }
    else if(DRV_FROM_AT(lchip))
    {
        sys_usw_dmps_port_info_t dmps_port_info = {0};
        dmps_port_info.gport = gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &index));
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));
        lchip = SYS_PP_BASE(lchip) + pp_id;
    }
    else
    {
        index = chan_id;
    }
    
    if (SYS_PORT_FRAMESIZE_TYPE_MIN == type)
    {
        cmd = DRV_IOR(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        *p_value  = GetDsChannelizeMode(V,portMinLen_f,&ds);
    }
    else if (SYS_PORT_FRAMESIZE_TYPE_MAX == type)
    {
        cmd = DRV_IOR(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        *p_value  = GetDsChannelizeMode(V,portMaxLen_f,&ds);
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_set_chan_framesize(uint8 lchip, uint32 chan_id, uint32 value, sys_port_framesize_type_t type)
{
    uint32 cmd = 0;
    uint32 entry_id = 0;
    uint16 dp_chan_id    = 0;
    uint8 pp_id = 0;
    uint8 dp_id = 0;
    ds_t   ds;

    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set mac_id:%d, type:%d.\n", chan_id, value);

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        dp_id = (chan_id < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))? 0:1;
        dp_chan_id = (chan_id < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))? chan_id:(chan_id - MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM));
        entry_id = DRV_INS(dp_id, dp_chan_id);
    }
    else if (DRV_FROM_AT(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_sub_chan_by_chan(lchip, 1, chan_id, &dp_chan_id, &pp_id, &dp_id));
        if (SYS_COMMON_USELESS_CHANNEL == dp_chan_id)
        {
            return CTC_E_NONE;
        }
        entry_id = dp_chan_id;
        lchip = SYS_PP_BASE(lchip) + pp_id;
    }
    else
    {
        entry_id = chan_id;
    }
    
    if (SYS_PORT_FRAMESIZE_TYPE_MIN == type)
    {
        cmd = DRV_IOR(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetDsChannelizeMode(V,portMinLen_f,&ds,value);
        cmd = DRV_IOW(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }
    else if (SYS_PORT_FRAMESIZE_TYPE_MAX == type)
    {
        cmd = DRV_IOR(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
        SetDsChannelizeMode(V,portMaxLen_f,&ds,value);
        cmd = DRV_IOW(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, DRV_CMD_DP_EN(cmd, dp_id), &ds));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_set_framesize(uint8 lchip, uint32 gport, uint32 value, sys_port_framesize_type_t type)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;
    uint32 port_type = 0;
    uint32 chan_id[SYS_USW_MAX_CHANEL_NUM_PER_PORT] = {0};
    uint8 chan_num = 0;
    uint8 index = 0;
    uint32 cmd  = 0;
    uint32 tbl_id   = 0;
    uint32 rx_en = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " MAC is not used \n");
        return CTC_E_INVALID_CONFIG;
    }
    if (DRV_IS_TSINGMA(lchip))
    {
        sys_datapath_lport_attr_t* p_port_cap = NULL;
        QuadSgmacDebugStatus0_m Sgmac_Status;
        uint32 eop_cnt = 0;
        uint32 sop_cnt = 0;
        uint32 sgmac_table_id = 0;
        uint16 step = 0;
        uint8 internal_mac_idx = 0;
        CTC_ERROR_RETURN(sys_usw_mac_get_port_capability(lchip, lport, &p_port_cap));
        internal_mac_idx = p_port_cap->internal_mac_idx;
        /* cfg sgmac Rx*/
        step = Sgmac1RxCfg0_t - Sgmac0RxCfg0_t;
        tbl_id = Sgmac0RxCfg0_t + internal_mac_idx*step + p_port_cap->sgmac_idx;

        cmd = DRV_IOR(tbl_id, Sgmac0RxCfg0_cfgSgmac0RxPktEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &rx_en));

        cmd = DRV_IOW(tbl_id, Sgmac0RxCfg0_cfgSgmac0RxPktEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &sop_cnt));
        step = QuadSgmacDebugStatus1_t - QuadSgmacDebugStatus0_t;
        sgmac_table_id = QuadSgmacDebugStatus0_t + (p_port_cap->tbl_id/4)*step;
        step = QuadSgmacDebugStatus1_dbgSgmac1RxEopCnt_f - QuadSgmacDebugStatus1_dbgSgmac0RxEopCnt_f;

        while(1)
        {
            if((index++) > 50)
            {
                ret = CTC_E_HW_TIME_OUT;
                goto roll_back;
            }
            else
            {
                /*verify no packet in sop */
                cmd = DRV_IOR(sgmac_table_id, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &Sgmac_Status),ret,roll_back);
                eop_cnt = GetQuadSgmacDebugStatus0(V,dbgSgmac0RxEopCnt_f+step*internal_mac_idx,&Sgmac_Status);
                sop_cnt = GetQuadSgmacDebugStatus0(V,dbgSgmac0RxSopCnt_f+step*internal_mac_idx,&Sgmac_Status);
                if(eop_cnt == sop_cnt)
                {
                    break;
                }
                sal_task_sleep(20);
            }
        }
    }
    CTC_ERROR_GOTO(sys_usw_port_get_channel(lchip, 1, gport, chan_id, &chan_num), ret, roll_back);
    if (CTC_IS_MCHAN_PORT(gport))
    {
        CTC_ERROR_GOTO(_sys_tsingma_port_set_chan_framesize(lchip, chan_id[0], value, type), ret, roll_back);
    }
    else
    {
        for (index = 0; index < chan_num; index++)
        {
            CTC_ERROR_GOTO(_sys_tsingma_port_set_chan_framesize(lchip, chan_id[index], value, type), ret, roll_back);
        }
    }

roll_back:
    if (DRV_IS_TSINGMA(lchip))
    {
        cmd = DRV_IOW(tbl_id, Sgmac0RxCfg0_cfgSgmac0RxPktEn_f);
        DRV_FIELD_IOCTL(lchip, 0, cmd, &rx_en);
    }

    return ret;
}

STATIC int32
_sys_tsingma_port_get_framesize(uint8 lchip, uint32 gport, uint32* p_value, sys_port_framesize_type_t type)
{
    uint16 lport = 0;
    uint32 value = 0;
    uint32 port_type = 0;
    uint32 chan_id[SYS_USW_MAX_CHANEL_NUM_PER_PORT] = {0};
    uint8  chan_num = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " MAC is not used \n");
        return CTC_E_INVALID_CONFIG;
    }
    CTC_ERROR_RETURN(sys_usw_port_get_channel(lchip, 1, gport, &chan_id[0], &chan_num));
    CTC_ERROR_RETURN(_sys_tsingma_port_get_chan_framesize(lchip, chan_id[0], gport, &value, type));
    *p_value = value;

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_set_max_frame(uint8 lchip, uint32 gport, uint32 value)
{
    if ((value < MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MIN_VALUE)) || (value > MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE)))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(_sys_tsingma_port_set_framesize(lchip, gport, value, SYS_PORT_FRAMESIZE_TYPE_MAX));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_get_max_frame(uint8 lchip, uint32 gport, uint32* p_value)
{
    uint32 value = 0;

    CTC_ERROR_RETURN(_sys_tsingma_port_get_framesize(lchip, gport, &value, SYS_PORT_FRAMESIZE_TYPE_MAX));
    *p_value = value;

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_set_min_frame_size(uint8 lchip, uint32 gport, uint32 size)
{

    if ((size < MCHIP_CAP(SYS_CAP_PORT_MIN_FRAMESIZE_MIN_VALUE))
       || (size > MCHIP_CAP(SYS_CAP_PORT_MIN_FRAMESIZE_MAX_VALUE)))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(_sys_tsingma_port_set_framesize(lchip, gport, size, SYS_PORT_FRAMESIZE_TYPE_MIN));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_get_min_frame_size(uint8 lchip, uint32 gport, uint8* p_size)
{
    uint32 size = 0;

    CTC_ERROR_RETURN(_sys_tsingma_port_get_framesize(lchip, gport, &size, SYS_PORT_FRAMESIZE_TYPE_MIN));
    *p_size = size;

    return CTC_E_NONE;
}

int32
sys_tsingma_port_set_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, uint32 value)
{
    int32   ret = CTC_E_NONE;
    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set port property, gport:0x%04X, property:%d, value:%d\n", \
                     gport, port_prop, value);

    switch (port_prop)
    {
    case CTC_PORT_PROP_MAX_FRAME_SIZE:
        ret = _sys_tsingma_port_set_max_frame(lchip, gport, value);
        break;

    case CTC_PORT_PROP_MIN_FRAME_SIZE:
        ret = _sys_tsingma_port_set_min_frame_size(lchip, gport, value);
        break;
    default:
        return CTC_E_NOT_SUPPORT;
    }

    if (ret != CTC_E_NONE)
    {
        return ret;
    }

    return CTC_E_NONE;
}
/**
@brief    Get port's properties according to gport id
*/
int32
sys_tsingma_port_get_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, uint32* p_value)
{
    uint8  value8 = 0;
    int32  ret = CTC_E_NONE;
    uint16 lport = 0;
    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get port property, gport:0x%04X, property:%d!\n", gport, port_prop);

    /*Sanity check*/
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    /* zero value */
    *p_value = 0;

    switch (port_prop)
    {
    case CTC_PORT_PROP_MAX_FRAME_SIZE:
        ret = _sys_tsingma_port_get_max_frame(lchip, gport, (ctc_frame_size_t*)p_value);
        break;
    case CTC_PORT_PROP_MIN_FRAME_SIZE:
        ret = _sys_tsingma_port_get_min_frame_size(lchip, gport, &value8);
        *p_value = value8;
        break;
    default:
        return CTC_E_NOT_SUPPORT;
    }

    if (ret != CTC_E_NONE)
    {
        return ret;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_framesize_init(uint8 lchip)
{
    uint32 cmd;
    uint32 valueMin = SYS_USW_MIN_FRAMESIZE_DEFAULT_VALUE;
    uint32 valueMax = SYS_USW_MAX_FRAMESIZE_DEFAULT_VALUE;
    ds_t   ds;

    cmd = DRV_IOR(NetRxMiscChanPktLenChkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetNetRxMiscChanPktLenChkCtl(V,cfgMiscMinLen_f,&ds,valueMin);
    cmd = DRV_IOW(NetRxMiscChanPktLenChkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(NetRxMiscChanPktLenChkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetNetRxMiscChanPktLenChkCtl(V,cfgMiscMaxLen_f,&ds,valueMax);
    cmd = DRV_IOW(NetRxMiscChanPktLenChkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_port_chan_init(uint8 lchip)
{
    uint32 field = 0;
    uint32 cmd = 0;
    uint32 cmdr = 0;
    uint32 cmdw = 0;
    NetRxCtl_m net_rx_ctl;
    NetTxMiscCtl_m net_tx_misc_ctl;
    EpeHeaderEditPhyPortMap_m epe_map;
    QWriteGuaranteeCtl_m guar_ctl;
    uint32 channel_id = 0;
    ds_t  ds;
    uint32 channel_num = 0;
    uint8 pp_id = 0;
    uint8 dp_id = 0;
    CTC_ERROR_RETURN(_sys_tsingma_port_framesize_init(lchip));
    sal_memset(&epe_map, 0, sizeof(EpeHeaderEditPhyPortMap_m));
    cmd = DRV_IOR(QWriteGuaranteeCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &guar_ctl));
    SetEpeHeaderEditPhyPortMap(V, portVlanBase_f, &epe_map, SYS_USW_MAX_VLAN_BASE);
    cmd = DRV_IOW(EpeHeaderEditPhyPortMap_t, DRV_ENTRY_FLAG);
    cmdr = DRV_IOR(DsQWriteGuarantee_t, DRV_ENTRY_FLAG);
    cmdw = DRV_IOW(DsQWriteGuarantee_t, DRV_ENTRY_FLAG);
    channel_num = DRV_FROM_AT(lchip) ? MCHIP_CAP(SYS_CAP_CHANNEL_NUM) : MCHIP_CAP(SYS_CAP_PER_DP_PHY_PORT_NUM);
    for (channel_id = 0; channel_id < channel_num; channel_id++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmd, &epe_map));
        if ((DRV_FROM_TMM(lchip) && SYS_USW_MISC_CHANNEL(channel_id % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))) ||
            (DRV_FROM_AT(lchip) && SYS_USW_MISC_CHANNEL(channel_id)))
        {
            continue;
        }
        if (DRV_IS_TSINGMA(lchip))
        {
            SetQWriteGuaranteeCtl(V, array_0_destGuaranteeChannel_f + channel_id, &guar_ctl, channel_id);
        }
        else
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmdr, &ds));
            SetDsQWriteGuarantee(V, destGuaranteeChannel_f, &ds, MCHIP_CAP(SYS_CAP_CHANID_DROP));
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmdw, &ds));
        }
        CTC_ERROR_RETURN(_sys_tsingma_port_set_chan_framesize(lchip, channel_id, SYS_USW_MAX_FRAMESIZE_DEFAULT_VALUE, SYS_PORT_FRAMESIZE_TYPE_MAX));
        CTC_ERROR_RETURN(_sys_tsingma_port_set_chan_framesize(lchip, channel_id, SYS_USW_MIN_FRAMESIZE_DEFAULT_VALUE, SYS_PORT_FRAMESIZE_TYPE_MIN));
    }
    cmd = DRV_IOW(QWriteGuaranteeCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &guar_ctl));

    for (pp_id = 0; pp_id < SYS_PP_NUM(lchip); pp_id++)
    {
        lchip = SYS_PP_BASE(lchip) + pp_id;
        for (dp_id = 0; dp_id < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp_id++)
        {
            cmd = DRV_IOR(NetRxCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &net_rx_ctl));
            SetNetRxCtl(V, underLenChkEn_f, &net_rx_ctl, 1);
            SetNetRxCtl(V, cfgOverLenWithErr_f, &net_rx_ctl, 1);
            SetNetRxCtl(V, bpduChkEn_f, &net_rx_ctl, 0);
            cmd = DRV_IOW(NetRxCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &net_rx_ctl));
        }
    }

    cmd = DRV_IOR(NetTxMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &net_tx_misc_ctl));

    SetNetTxMiscCtl(V, runtDropEn_f, &net_tx_misc_ctl, 1);
    /* RTL logic is discard packet, when packet length <= cfgMinPktLen */
    SetNetTxMiscCtl(V, cfgMinPktLen0_f, &net_tx_misc_ctl, (MCHIP_CAP(SYS_CAP_PORT_MIN_FRAMESIZE_MIN_VALUE) - 1));

    cmd = DRV_IOW(NetTxMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &net_tx_misc_ctl));

    /* RTL logic is discard packet, when egressHeaderAdjust output packet's length <= minPktLen */
    field = 5;
    cmd = DRV_IOR(EpeHdrAdjustMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetEpeHdrAdjustMiscCtl(V,minPktLen_f,&ds,field);
    cmd = DRV_IOW(EpeHdrAdjustMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    return CTC_E_NONE;
}

int32
sys_tsingma_port_init(uint8 lchip)
{
    if (DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_MDIO_XG_CHANGE_0, sys_usw_peri_phy_link_change_isr));
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_MDIO_XG_CHANGE_1, sys_usw_peri_phy_link_change_isr));
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MDIO_XG_CHANGE_0, sys_usw_peri_phy_link_change_isr));
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MDIO_XG_CHANGE_1, sys_usw_peri_phy_link_change_isr));
    }
    CTC_ERROR_RETURN(_sys_tsingma_port_chan_init(lchip));
    return CTC_E_NONE;
}

int32
sys_tsingma_port_set_xpipe_en(uint8 lchip, uint32 gport, uint32 value)
{
    uint32  index = 0;
    uint32  port_mac_id = 0;
    uint32  old_type = 0;
    uint32  port_chan_id = 0;
    uint32  port_pchan_id = 0;
    uint32  tmp_value = 0;
    uint32  cmd = 0;
    uint32  step = 0;
    uint32  srcGuaranteeEn[32] = {0};
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_get_property(lchip, gport, CTC_PORT_PROP_XPIPE_EN, &old_type));
    /* mac id channel id and port id is equal */
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&port_mac_id));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, (void *)&port_chan_id));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_GET_PMAC_CHAN_ID, (void *)&port_pchan_id));

    CTC_ERROR_RETURN(sys_usw_dmps_set_port_property(lchip, gport, SYS_PORT_API_DMPS_PROP_XPIPE_RX, (void *)&value));

    cmd = DRV_IOR(NetRxCtl_t, NetRxCtl_portSplitEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);
    /* index = {macid[5:3] macid[1:0]} */
    index = ((port_mac_id & 0x38) >> 1) | (port_mac_id & 0x3);
    if (value)
    {
        CTC_BIT_SET(tmp_value, index);
    }
    else
    {
        CTC_BIT_UNSET(tmp_value, index);
    }
    cmd = DRV_IOW(NetRxCtl_t, NetRxCtl_portSplitEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);
    cmd = DRV_IOW(NetTxPortSplitEnCtl_t, NetTxPortSplitEnCtl_portSplitEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

    /* set srcGuaranteeEn and destGuaranteeChannel */
    cmd = DRV_IOR(QWriteGuaranteeCtl_t, QWriteGuaranteeCtl_srcGuaranteeEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, srcGuaranteeEn);

    if (value)
    {
        /* tm pmac channel and emac channel is fix, if get emac channel is 255 datapath will return error*/
        CTC_BIT_SET(srcGuaranteeEn[port_pchan_id / BITS_NUM_OF_WORD], port_pchan_id % BITS_NUM_OF_WORD);
    }
    else
    {
        CTC_BIT_UNSET(srcGuaranteeEn[port_chan_id / BITS_NUM_OF_WORD], port_chan_id % BITS_NUM_OF_WORD);
        if ((CTC_CONST256 - 1) != port_pchan_id && CTC_PORT_XPIPE_TYPE_5 != old_type)
        {
            CTC_BIT_UNSET(srcGuaranteeEn[port_pchan_id / BITS_NUM_OF_WORD], port_pchan_id % BITS_NUM_OF_WORD);
        }
    }
    step = QWriteGuaranteeCtl_array_1_destGuaranteeChannel_f - QWriteGuaranteeCtl_array_0_destGuaranteeChannel_f;
    cmd = DRV_IOW(QWriteGuaranteeCtl_t, QWriteGuaranteeCtl_array_0_destGuaranteeChannel_f + step * port_chan_id);
    DRV_FIELD_IOCTL(lchip, 0, cmd, (value? &port_pchan_id: &port_chan_id));
    cmd = DRV_IOW(QWriteGuaranteeCtl_t, QWriteGuaranteeCtl_srcGuaranteeEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, srcGuaranteeEn);

    if (CTC_PORT_XPIPE_TYPE_3 == value)
    {
        tmp_value = SYS_USW_XPIPE_RSV_PORT;
        cmd = DRV_IOW(IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_pchan_id, cmd, &tmp_value));
    }

    return CTC_E_NONE;
}


